package com.flashidea.zddziot.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PathEffect;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import com.flashidea.zddziot.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/*- 在res->values资源文件中创建一个名为attrs的xml文件，使用自定义属性时要在布局中加入
 * “xmlns:环境名="http://schemas.android.com/apk/res/包名"”
 环境名:centreDrawable=""
 该文件内容如下：
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
 <declare-styleable name="CustomView">
 <!-- centreDrawable:圆中心的图标 -->
 <attr name="centreDrawable" format="reference" />
 <!-- centreBackground:圆中心的图标 的背景 -->
 <attr name="centreBackground" format="reference" />
 <!-- broadsideBackground:圆边上按钮的图标 的背景 -->
 <attr name="broadsideBackground" format="reference" />
 <!-- circleBorderSize:圆边的大小,默认 1 -->
 <attr name="circleBorderSize" format="dimension|reference" />
 <!-- circleBorderColor:圆边的颜色,默认 WHITE -->
 <attr name="circleBorderColor" format="color|reference" />
 </declare-styleable>
 </resources>
 */
/**
 * 自定义圆形旋转两级菜单按钮，支持xml布局修改属性，增加了扩散动画
 *
 * @author jinhui
 */
/**
 * @ClassName: RoundAnimView
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author jinhui 1349832178@qq.com
 * @date 2015年4月17日 下午4:16:06
 *
 */
public class RoundAnimView extends View {

	/**
	 * 画笔
	 */
	private Paint mPaint;
//	private PaintFlagsDrawFilter pfd;
	/**
	 * 菜单对象集合
	 */
	private List<MenuItemObject> menus = new ArrayList<MenuItemObject>();
	/**
	 * 当前菜单集合
	 */
	private List<Object> menu;
	/**
	 * 一级菜单 集合
	 */
	private List<Object> menuOneLevel;
	/**
	 * 二级菜单集合
	 */
	private Map<Object, List<Object>> menuTwoLevel;
	private GestureDetector mGestureDetector;
	/**
	 * 自定义事件监听器
	 */
	private OnRoundItemClickListener onRoundItemClickListener;
	/**
	 * 圆心坐标
	 */
	private int cx, cy;
	/**
	 * 菜单控件半径
	 */
	private int menuControlRadius;
	/**
	 * 单个菜单项半径
	 */
	private int menuItemRadius;
	/**
	 * 每两个点间隔的角度
	 */
	private int mDegreeDelta;
	/**
	 * 中心按钮图标
	 */
	private Bitmap centreBitmap;
	/**
	 * 中心按钮背景
	 */
	private Bitmap centreBackground;
	/**
	 * 圆边上按钮背景
	 */
	private Bitmap broadsideBackground;
	/**
	 * 菜单状态标志
	 */
	private int menuOpenState = -1;
	/**
	 * 记录上级菜单的位置
	 */
	private int parentPosition = -1;
	/**
	 * 记录上级菜单
	 */
	private Object parent;
	/**
	 * 刻度线颜色
	 */
	private int rateColor = Color.WHITE;
	/**
	 * 刻度线大小
	 */
	private float rateSize = 1;
	/**
	 * 长刻度线的长度
	 */
	private float longLine = 20;
	/**
	 * 短刻度线的长度
	 */
	private float shortLine = 10;
	private float density;
	/**
	 * 字体大小
	 */
	private float textSize;

	/**
	 * 获取字体大小
	 *
	 * @return
	 */
	public float getTextSize() {
		return textSize;
	}

	/**
	 * 设置字体大小
	 *
	 * @param textSize
	 */
	public void setTextSize(float textSize) {
		this.textSize = textSize;
	}

	/**
	 * 设置刻度线的大小
	 */
	public void setRateColor(int rateColor) {
		this.rateColor = rateColor;
		rotateButtons(0);
	}

	/**
	 * 设置刻度线大小
	 */
	public void setRateSize(float rateSize) {
		this.rateSize = rateSize;
		rotateButtons(0);
	}

	/**
	 * 设置长刻度线的长度
	 */
	public void setLongLine(float longLine) {
		this.longLine = longLine;
		rotateButtons(0);
	}

	/**
	 * 设置短刻度线的长度
	 */
	public void setShortLine(float shortLine) {
		this.shortLine = shortLine;
		rotateButtons(0);
	}

	/**
	 * 音量角度
	 */
	private int angle = -90;

	/**
	 * 获取角度
	 */
	public double getAngle() {
		return angle;
	}

	/**
	 * 设置角度
	 */
	public void setAngle(int angle) {
		this.angle = angle;
		if (menuOpenState == -1) {
			menus.get(0).angle = angle;
		}
		rotateButtons(0);
	}

	/**
	 * 角度变化回调监听
	 */
	private OnAngleChangeListener listener;

	/**
	 * 设置角度变化回调监听
	 *
	 * @param listener
	 */
	public void setOnAngleChangeListener(OnAngleChangeListener listener) {
		this.listener = listener;
	}

	/**
	 * 对每个象限触摸情况的记录
	 */
	private boolean[] quadrantTouched = new boolean[] { false, false, false, false, false };
	private final static int TO_ROTATE_BUTTON = 0;  // 旋转按钮；
	private Handler handler = new Handler() {

		public void handleMessage(Message msg) {
			switch (msg.what) {
				case TO_ROTATE_BUTTON:
					float velocity = (Float) msg.obj;
					rotateButtons((int) (velocity / 75));
					velocity /= 1.0666F;
					new Thread(new FlingRunnable(velocity)).start();
					break;
				default:
					break;
			}
		};
	};
	/**
	 * 音量图标
	 */
	private Bitmap volumeBitmap;
	private Bitmap backgroundBitmap;

	/**
	 * 设置音量图标
	 *
	 * @param bitmap
	 */
	public void setVolumeBitmap(Bitmap bitmap) {
		this.volumeBitmap = bitmap;
		rotateButtons(0);
	}

	/**
	 * 获取一级菜单集合
	 */
	public List<Object> getMenuOneLevel() {
		return menuOneLevel;
	}

	/**
	 * 设置一级菜单集合
	 *
	 * @param list
	 */
	public void setMenuOneLevel(List<Object> list) {
		this.menuOneLevel = list;
		setupStones();
		rotateButtons(0);
	}

	/**
	 * 获取二级菜单集合
	 */
	public Map<Object, List<Object>> getMenuTwoLevel() {
		return menuTwoLevel;
	}

	/**
	 * 设置二级菜单图片id
	 *
	 * @param map
	 *            菜单集合 Map<key,value><br>
	 *            key：一级菜单项对应对象<br>
	 *            value：一级菜单项对应的二级菜单集合
	 */
	public void setMenuTwoLevel(Map<Object, List<Object>> map) {
		this.menuTwoLevel = map;
		setupStones();
		rotateButtons(0);
	}

	/**
	 * 设置中心菜单开关的Bitmap
	 *
	 * @param bitmap
	 */
	public void setCentreBitmap(Bitmap bitmap) {
		this.centreBitmap = bitmap;
		setupStones();
		rotateButtons(0);
	}

	/**
	 * 设置菜单项的点击事件
	 *
	 * @param listener
	 */
	public void setOnRoundItemClickListener(OnRoundItemClickListener listener) {
		this.onRoundItemClickListener = listener;
	}

	public RoundAnimView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(context, attrs);
	}

	public RoundAnimView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs);
	}

	private void init(Context context, AttributeSet attrs) {
		density = getResources().getDisplayMetrics().density;
		TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
		longLine = typeArray.getDimension(R.styleable.CustomView_longLine, 10);
		shortLine = typeArray.getDimension(R.styleable.CustomView_shortLine, 5);
		rateColor = typeArray.getColor(R.styleable.CustomView_rateColor, Color.WHITE);
		rateSize = typeArray.getDimension(R.styleable.CustomView_rateSize, 1);
		textSize = typeArray.getDimension(R.styleable.CustomView_textSize, 12);
		int resourceId = typeArray.getResourceId(R.styleable.CustomView_centreDrawable,
			R.drawable.app_icon);
		centreBitmap = BitmapFactory.decodeResource(getResources(), resourceId);
		resourceId = typeArray.getResourceId(R.styleable.CustomView_centreBackground, -1);
		if (resourceId != -1) {
			centreBackground = BitmapFactory.decodeResource(getResources(), resourceId);
		}
		resourceId = typeArray.getResourceId(R.styleable.CustomView_broadsideBackground, -1);
		if (resourceId != -1) {
			broadsideBackground = BitmapFactory.decodeResource(getResources(), resourceId);
		}
		resourceId = typeArray.getResourceId(R.styleable.CustomView_volumeDrawable, -1);
		if (resourceId != -1) {
			volumeBitmap = BitmapFactory.decodeResource(getResources(), resourceId);
		}
		resourceId = typeArray.getResourceId(R.styleable.CustomView_backgroundDrawable,
			R.drawable.rotary_knob);
		backgroundBitmap = BitmapFactory.decodeResource(getResources(), resourceId);
		float circleBorderSize = typeArray.getDimension(R.styleable.CustomView_circleBorderSize, 10);
		int circleBorderColor = typeArray.getColor(R.styleable.CustomView_circleBorderColor,
			Color.WHITE);
		/* 关闭资源 */
		typeArray.recycle();
//		pfd = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
		mGestureDetector = new GestureDetector(getContext(), new MyGestureListener());
		mPaint = new Paint();
		mPaint.setStyle(Style.STROKE); // 绘制空心圆
		mPaint.setColor(circleBorderColor);
		mPaint.setAntiAlias(true); // 消除锯齿
		mPaint.setStrokeWidth(circleBorderSize);
		setupStones();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int measuredWidth = getMeasuredWidth();
		int measuredHeight = getMeasuredHeight();
		if (measuredWidth > measuredHeight) {
			setMeasuredDimension(measuredHeight, measuredHeight);
		} else {
			setMeasuredDimension(measuredWidth, measuredWidth);
		}
		cx = getMeasuredWidth() / 2;
		cy = getMeasuredHeight() / 2;
		// 初始化半径和菜单半径
		menuControlRadius = cx < cy ? cx / 5 * 3 : cy / 5 * 3;
		menuItemRadius = (int) (cx < cy ? cx / 5.5 : cy / 5.5);
		computeCoordinates(menuControlRadius);
	}

	@Override
	public void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 画音量调节按钮
		if (menuOpenState == -1) {
			drawLines(canvas);
		} else {
			drawMenuItem(canvas);
		}
		// 画中心按钮背景
		if (centreBackground != null) {
			drawInCenter(canvas, centreBackground, cx, cy, menuItemRadius);
		}
		// 画中心按钮
		if (centreBitmap != null) {
			drawInCenter(canvas, centreBitmap, cx, cy, menuItemRadius);
		}
	}

	/**
	 * 画菜单项
	 *
	 * @param canvas
	 */
	private void drawMenuItem(Canvas canvas) {
		// 将每个菜单画出来
		for (int index = 0; index < menus.size(); index++) {
			MenuItemObject menuItem = menus.get(index);
			if (broadsideBackground != null) {
				drawInCenter(canvas, broadsideBackground, menuItem.x, menuItem.y, menuItemRadius);
			}
			if (menuItem.obj != null) {
				drawInCenter(canvas, menuItem.obj, menuItem.x, menuItem.y, menuItemRadius);
			}
		}
	}

	/**
	 * 画刻度
	 *
	 * @param canvas
	 */
	private void drawLines(Canvas canvas) {
		Paint paint = new Paint();
		paint.setColor(rateColor);
		paint.setAntiAlias(true);
		paint.setStrokeWidth(rateSize * density);
		paint.setStyle(Style.STROKE);
		PathEffect effect = new DashPathEffect(new float[] { 8 * density, 10 * density,
				8 * density, 10 * density }, 1);
		paint.setPathEffect(effect);
		Bitmap bitmap;
		if (menu.get(0) instanceof Integer) {
			bitmap = BitmapFactory.decodeResource(getResources(), (Integer) menu.get(0));
		} else if (menu.get(0) instanceof Bitmap) {
			bitmap = (Bitmap) menu.get(0);
		} else {
			bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.circle_red);
		}
		int r = bitmap.getWidth() > bitmap.getHeight() ? bitmap.getWidth() / 2
														: bitmap.getHeight() / 2;
		RectF oval = new RectF(cx - menuControlRadius - r, cy - menuControlRadius - r, cx
			+ menuControlRadius + r, cy + menuControlRadius + r);
		canvas.drawArc(oval, 135, 270, false, paint);
		float lx = cx
			+ (float) ((menuControlRadius + r + longLine) * Math.cos(Math.toRadians(135)));
		float ly = cy
			+ (float) ((menuControlRadius + r + longLine) * Math.sin(Math.toRadians(135)));
		canvas.drawLine(cx, cy, lx, ly, paint);
		lx = cx + (float) ((menuControlRadius + r + longLine) * Math.cos(Math.toRadians(45)));
		ly = cy + (float) ((menuControlRadius + r + longLine) * Math.sin(Math.toRadians(45)));
		canvas.drawLine(cx, cy, lx, ly, paint);
		drawBackground(canvas, bitmap);
	}

//	private void drawLines(Canvas canvas) {
//		Paint paint = new Paint();
//		paint.setColor(rateColor);
//		paint.setAntiAlias(true);
//		paint.setStrokeWidth(rateSize);
//		Bitmap bitmap;
//		if (menu.get(0) instanceof Integer) {
//			bitmap = BitmapFactory.decodeResource(getResources(), (Integer) menu.get(0));
//		} else if (menu.get(0) instanceof Bitmap) {
//			bitmap = (Bitmap) menu.get(0);
//		} else {
//			bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.circle);
//		}
//		int r = bitmap.getWidth() > bitmap.getHeight() ? bitmap.getWidth() / 2
//		                                               : bitmap.getHeight() / 2;
//		int count = -1;
//		for (int i = 0; i < 360; i += 20) {
//			float lx, ly;
//			if (++count % 2 == 0) {
//				paint.setStrokeWidth((float) (rateSize * 1.2));
//				lx = cx
//						+ (float) ((menuControlRadius + longLine + r) * Math.cos(Math.toRadians(i)));
//				ly = cy
//						+ (float) ((menuControlRadius + longLine + r) * Math.sin(Math.toRadians(i)));
//			} else {
//				paint.setStrokeWidth((float) (rateSize * 0.8));
//				lx = cx
//						+ (float) ((menuControlRadius + shortLine + r) * Math.cos(Math.toRadians(i)));
//				ly = cy
//						+ (float) ((menuControlRadius + shortLine + r) * Math.sin(Math.toRadians(i)));
//			}
//			canvas.drawLine(cx, cy, lx, ly, paint);
//		}
//		drawBackground(canvas, bitmap);
//	}
	/**
	 * 画按钮背景
	 *
	 * @param canvas
	 * @param bitmap
	 * @param bitmap
	 */
	private void drawBackground(Canvas canvas, Bitmap bitmap) {
		Paint paint = new Paint();
		paint.setColor(rateColor);
		paint.setAntiAlias(true);
		paint.setStrokeWidth(rateSize);
		int r = bitmap.getWidth() > bitmap.getHeight() ? bitmap.getWidth() / 2
														: bitmap.getHeight() / 2;
		Rect dst = new Rect();
		dst.left = (int) (cx - menuControlRadius - r);
		dst.right = (int) (cx + menuControlRadius + r);
		dst.top = (int) (cy - menuControlRadius - r);
		dst.bottom = (int) (cy + menuControlRadius + r);
		canvas.drawBitmap(backgroundBitmap, null, dst, paint);
		computeCoordinates(menuControlRadius - r / 2);
		float x = menus.get(0).x;
		float y = menus.get(0).y;
		dst.left = (int) (x - r);
		dst.right = (int) (x + r);
		dst.top = (int) (y - r);
		dst.bottom = (int) (y + r);
		canvas.drawBitmap(bitmap, null, dst, paint);
	}

	/**
	 * 把中心点放到中心处
	 *
	 * @param canvas
	 * @param obj
	 * @param left
	 * @param top
	 * @param radius
	 */
	private void drawInCenter(Canvas canvas, Object obj, float left, float top, float radius) {
		Rect dst = new Rect();
		dst.left = (int) (left - radius);
		dst.right = (int) (left + radius);
		dst.top = (int) (top - radius);
		dst.bottom = (int) (top + radius);
		Paint paint = new Paint();
		paint.setColor(mPaint.getColor());
		paint.setStrokeWidth(2);
		paint.setAntiAlias(true); // 消除锯齿
		paint.setStyle(Style.STROKE);
		// 画按钮背景
		canvas.drawCircle(left, top, radius, paint);
		if (obj instanceof Integer) {
			canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), (Integer) obj), null,
				dst, mPaint);
		} else if (obj instanceof Bitmap) {
			canvas.drawBitmap((Bitmap) obj, null, dst, mPaint);
		} else if (obj instanceof CharSequence) {
			String text = (String) obj;
			paint = new Paint();
			paint.setColor(mPaint.getColor());
			paint.setTextSize(textSize * density);
			paint.setAntiAlias(true); // 消除锯齿
			float width = paint.measureText(text);
			canvas.drawText(text, 0, text.length(), left - width / 2, top
				+ paint.getFontMetrics().bottom, paint);
		}
	}

	/**
	 * 初始化每个点
	 */
	private void setupStones() {
		menus.clear();
		if (menuOpenState == 0) {
			menu = menuOneLevel;
		} else if (menuOpenState == -1) {
			menu = new ArrayList<Object>();
			if (volumeBitmap != null) {
				menu.add(volumeBitmap);
			} else {
				menu.add(R.drawable.circle_red);
			}
		}
		if (menu == null || menu.size() == 0) {
			return;
		}
		int angle = 270;
		mDegreeDelta = 360 / menu.size();
		for (int index = 0; index < menu.size(); index++) {
			MenuItemObject menuItem = new MenuItemObject();
			if (angle >= 360) {
				angle -= 360;
			} else if (angle < 0) {
				angle += 360;
			}
			menuItem.angle = menuOpenState == -1 ? this.angle : angle;
			menuItem.obj = menu.get(index);
			angle += mDegreeDelta;
			menus.add(menuItem);
		}
	}

	/**
	 * 计算每个点的坐标
	 *
	 * @param radius
	 *            半径
	 */
	private void computeCoordinates(int radius) {
		for (int index = 0; index < menus.size(); index++) {
			MenuItemObject menuItem = menus.get(index);
			menuItem.x = cx + (float) (radius * Math.cos(Math.toRadians(menuItem.angle)));
			menuItem.y = cy + (float) (radius * Math.sin(Math.toRadians(menuItem.angle)));
		}
	}

	private int startAngle;

	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		int x, y;
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			x = (int) event.getX();
			y = (int) event.getY();
//			if (((x - cx) * (x - cx) + (y - cy) * (y - cy)) > Math.pow(menuControlRadius
//				+ (menuOpenState == -1 ? 20 : menuItemRadius), 2)) {
//				return false;
//			}
			startAngle = computeCurrentAngle(x, y);
		} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
			x = (int) event.getX();
			y = (int) event.getY();
			if (((x - cx) * (x - cx) + (y - cy) * (y - cy)) > Math.pow(menuControlRadius
				+ (menuOpenState == -1 ? 20 : menuItemRadius), 2)) {
				return false;
			}
			if (((x - cx) * (x - cx) + (y - cy) * (y - cy)) > menuItemRadius * menuItemRadius) {
				int currentAngle = computeCurrentAngle(x, y);
				if (menuOpenState == -1) {
					MenuItemObject menuItemObject = menus.get(0);
					angle = menuItemObject.angle;
				}
				rotateButtons(startAngle - currentAngle);
				startAngle = currentAngle;
			}
		}
		// set the touched quadrant to true
		quadrantTouched[getQuadrant(event.getX() - cx, cy - event.getY())] = true;
		mGestureDetector.onTouchEvent(event);
		return true;
	}

	private class MyGestureListener extends SimpleOnGestureListener {

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
			// get the quadrant of the start and the end of the fling
			int q1 = getQuadrant(e1.getX() - cx, cy - e1.getY());
			int q2 = getQuadrant(e2.getX() - cx, cy - e2.getY());
			// the inversed rotations
			if ((q1 == 2 && q2 == 2 && Math.abs(velocityX) < Math.abs(velocityY))
				|| (q1 == 3 && q2 == 3) || (q1 == 1 && q2 == 3)
				|| (q1 == 4 && q2 == 4 && Math.abs(velocityX) > Math.abs(velocityY))
				|| ((q1 == 2 && q2 == 3) || (q1 == 3 && q2 == 2))
				|| ((q1 == 3 && q2 == 4) || (q1 == 4 && q2 == 3))
				|| (q1 == 2 && q2 == 4 && quadrantTouched[3])
				|| (q1 == 4 && q2 == 2 && quadrantTouched[3])) {
				if (menuOpenState != -1) {
					new Thread(new FlingRunnable(velocityX + velocityY)).start();
				}
			} else {
				// the normal rotation
				if (menuOpenState != -1) {
					new Thread(new FlingRunnable(-(velocityX + velocityY))).start();
				}
			}
			return true;
		}

		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			int x = (int) e.getX();
			int y = (int) e.getY();
			int position = getInCircle(x, y);
			int centreRadius = Math.min(centreBitmap.getWidth() / 2, centreBitmap.getHeight() / 2);
			if (menuOpenState != -1 && position != -1 && menu != null) {
				Object object = menu.get(position);
				if (menuOpenState == 0 && menuTwoLevel != null) {
					List<Object> ceche = menuTwoLevel.get(menuOneLevel.get(position));
					if (parentPosition != -1) {
						parent = object;
					}
					if (ceche != null && ceche.size() > 0) {
						parentPosition = position;
						menu = ceche;
						menuOpenState = 1;
						position = -1;
					}
				} else {
					menuOpenState = -1;
				}
				if (onRoundItemClickListener != null) {
					onRoundItemClickListener.onRoundItemClick(parentPosition, parent, position,
						object);
				}
				setupStones();
				if (menuOpenState == -1) {
					computeCoordinates(menuControlRadius);
					invalidate();
				} else {
					new AnimThread().start();
				}
				return true;
			} else if (((x - cx) * (x - cx) + (y - cy) * (y - cy)) < centreRadius * centreRadius) {
				/*
				 * if (menuOpenState == 1 && menuOneLevel != null) {
				 * menuOpenState = 0; } else
				 */
				if (menuOpenState == 0) {
					menuOpenState = -1;
				} else {
					menuOpenState = 0;
				}
				parentPosition = -1;
				parent = null;
				if (onRoundItemClickListener != null) {
					onRoundItemClickListener.onRoundItemClick(parentPosition, parent, -1, null);
				}
				setupStones();
				if (menuOpenState == -1) {
					computeCoordinates(menuControlRadius);
					invalidate();
				} else {
					new AnimThread().start();
				}
				return true;
			}
			return false;
		}
	}

	/**
	 * 按钮的扩散动画
	 *
	 * @author jinhui
	 */
	private class AnimThread extends Thread {

		@Override
		public void run() {
			super.run();
			try {
				for (int i = 0; i <= menuControlRadius; i += 10) {
					computeCoordinates(i);
					postInvalidate();
					sleep(10);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 旋转菜单按钮
	 */
	private void rotateButtons(int degree) {
		for (int i = 0; i < menus.size(); i++) {
			MenuItemObject menuItem = menus.get(i);
			menuItem.angle -= degree;
			if (menuItem.angle < 0) {
				menuItem.angle += 360;
			} else if (menuItem.angle >= 360) {
				menuItem.angle -= 360;
			}
		}
		if (listener != null) {
			listener.onAngleChange(this, getId(), angle, -degree);
		}
		computeCoordinates(menuControlRadius);
		invalidate();
	}

	/**
	 * 获得该点所在的菜单项上
	 *
	 * @param x
	 * @param y
	 * @return
	 */
	private int getInCircle(int x, int y) {
		for (int i = 0; i < menus.size(); i++) {
			MenuItemObject menuItem = menus.get(i);
			int mx = (int) menuItem.x;
			int my = (int) menuItem.y;
			if (((x - mx) * (x - mx) + (y - my) * (y - my)) < menuItemRadius * menuItemRadius) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 获取坐标所在的象限
	 *
	 * @param x
	 *            x坐标
	 * @param y
	 *            y坐标
	 * @return
	 */
	private static int getQuadrant(double x, double y) {
		if (x >= 0) {
			return y >= 0 ? 1 : 4;
		} else {
			return y >= 0 ? 2 : 3;
		}
	}

	/**
	 * 计算某点的角度
	 *
	 * @param x
	 * @param y
	 * @return
	 */
	private int computeCurrentAngle(float x, float y) {
		float distance = (float) Math.sqrt(((x - cx) * (x - cx) + (y - cy) * (y - cy)));
		int degree = (int) (Math.acos((x - cx) / distance) * 180 / Math.PI);
		if (y < cy) {
			degree = -degree;
		}
		return degree;
	}

	/**
	 * 打开一级菜单
	 */
	public void openMenu() {
		System.out.println("openMenu");
		menuOpenState = 0;
		parentPosition = -1;
		parent = null;
		setupStones();
		rotateButtons(0);
	}

	/**
	 * 关闭菜单显示音量调节按钮
	 */
	public void closeMenu() {
		System.out.println("closeMenu");
		menuOpenState = -1;
		setupStones();
		rotateButtons(0);
	}

	/**
	 * 菜单是否打开
	 * 
	 * @return
	 */
	public boolean isMenuOpen() {
		return menuOpenState == 0;
	}

	private class FlingRunnable implements Runnable {

		private float velocity;

		public FlingRunnable(float velocity) {
			this.velocity = velocity;
		}

		@Override
		public void run() {
			if (Math.abs(velocity) >= 200) {
				Message message = Message.obtain();
				message.what = TO_ROTATE_BUTTON;
				message.obj = velocity;
				handler.sendMessage(message);
			}
		}
	}

	/**
	 * 菜单项点击回调接口
	 */
	public interface OnRoundItemClickListener {

		/**
		 * 点击菜单项的回调,只有-1和null为点击了中心按钮
		 *
		 * @param parentPosition
		 *            点击的菜单项的上级菜单位置,-1代表没有上级菜单
		 * @param parent
		 *            点击的菜单项的上级菜单对象，null代表没有上级菜单
		 * @param position
		 *            点击的菜单项位置，-1代表打开了菜单还没有点击
		 * @param clichMenu
		 *            点击的菜单项对应的对象，null代表打开了菜单还没有点击
		 */
		public void onRoundItemClick(int parentPosition, Object parent, int position,
				Object clichMenu);
	}

	/**
	 * 菜单项对象，保存图片，角度，坐标
	 */
	private class MenuItemObject {

		Object obj;
		/**
		 * 角度
		 */
		int angle;
		/**
		 * x坐标
		 */
		float x;
		/**
		 * y坐标
		 */
		float y;
		/**
		 * 是否可见
		 */
//		boolean isVisible = true;
	}
}
